;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 介绍：	上电后复位中断执行的内容：一般是Boot代码
; NOTE:		File format: UTF-8
; 作者		将狼才鲸
; 日期		2023-06-11
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	START_ROUTINE SEGMENT CODE AT 0100H	; 0100H地址的复位中断处理的代码段
	RSEG START_ROUTINE	; 1、RESET函数从RAM 0x100地址开始，将0xFF之前的RAM留给堆栈，
						; 堆栈之前是中断入口地址；
						; 2、注意：RAM地址（包含中断入口地址）和寄存器地址是分开的，它们地址
						; 重叠但含义不同，并不会相互干扰

	PUBLIC RESET	; 类似于C语言中的函数不使用static，让函数变成全局可调用的;
	EXTERN CODE (ASM_MAIN)	; extern void asm_main(void);
	EXTERN CODE (UART_INIT)
	EXTERN CODE (_MAIN)	; 1、声明.c文件中的main()函数，或者.asm中的_MAIN函数；C语言中的函数
						;	只要前面加上下划线，就能被汇编中识别；同样的，汇编中的函数
						;	如果前面有下划线，去掉下划线后就能被C语言代码识别；
						;	函数名会忽略大小写，_Main，_main都会有效
;;
; 包含头文件和其它源文件，也可以用#include <CORE8051.INC>，同样有效；
; 被包含的文件不要用END指令放在文件尾，否则编译器会报错
$INCLUDE(CONFIG.INC)		; 系统全局宏定义
$INCLUDE(CORE8051.INC)		; 中断号、堆栈地址等CPU相关宏定义，以及8051寄存器头文件引用

	; 标号以冒号:结尾，兼具C语言的标号和函数名的功能；可以跳转到标号处
;;
; 功能：类似于C语言的main()函数，是汇编程序主入口
; 参数：无
; 返回：无
;;
RESET:	
	NOP	; 空指令，消耗一个时钟周期的时间，什么也不做

	;; 系统初始化 ;;
	CLR EA	; 屏蔽所有中断
	MOV IE, #00H	; 关闭每一个中断；MOV指令类似于C语言的=赋值，IE = 0x00;
	CLR	RS0	; RS1 RS0的值为00时，选择R0~7的通用寄存器为4组中的第0组；
			; 清零一个位，标准C语言里没有直接的位操作，需要PSW &= ~RS0_MASK;（仅展示逻辑）
	CLR	RS1
	MOV DPTR, #00H	; 程序指针定位到复位中断处

	MOV SP, #ORG_STACK	; 1、当前本工程用的AT89C51芯片默认工程，未设置外部RAM配置，中断占的地址少，
						; 而内部RAM只有0x80大小，所以设置到0x3F
						; 2、程序运行开始时需要对SP堆栈地址进行设置，常用的8051单片机一般设置到80H之后，
						; 给堆栈留足空间，但是又不占用中断入口地址


	;; 外设模块初始化 ;;
	; 串口初始化
	LCALL UART_INIT	; 1、调用函数，C语言中类似的用法是your_func();
					; 2、LCALL和RET成对使用，跳转前会将当前地址放到堆栈，而LJMP遇到
					; 遇到RET也会返回，但会返回最开始的地址，或者返回到不知道哪里去了；
					; 3、单步执行到LCALL位置的话，想继续进入子函数，需要按F11，不能再按F10，
					; 按F10会一次性执行完子程序，并单步跳过子程序
	
	;LCALL TIMER0_INIT	; 定时器0初始化，可固定用作RTOS实时操作系统的系统嘀嗒tick
	;LCALL TIMER1_INIT	; 一般用作用户使用的串口
	;LCALL GPIO_INIT	; 4组IO口的初始化，输出固定电平或者作为输入之类
	
	LCALL ASM_MAIN	; 执行USER.ASM中的主函数

	;;
	; 汇编系统初始化完成后进入C语言主函数（也可把初始化全部放在C语言中完成，例如重新设置
	; 堆栈地址、配置中断使能等）
	LCALL _MAIN	; 跳转到C语言的main函数

LOOP:	; 汇编函数不遇到RET指令的话会一直往后执行，所以RESET这个主程序没被前面的main函数
		; 阻塞的话，就会进入下面的死循环
	NOP
	LJMP	LOOP

	END
